import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

import static java.lang.Thread.*;

/**
 * Created by sheep on 2016/1/27.
 */
public class WaxOMatic {
    public static void main(String[] args) throws InterruptedException {
        Car car = new Car();
        ExecutorService exec = Executors.newCachedThreadPool();
        exec.execute(new WaxOn(car));
        exec.execute(new WaxOff(car));
        TimeUnit.SECONDS.sleep(5);
        exec.shutdownNow();
    }

}

class Car {
    private boolean waxOn = false;

    public boolean isWaxOn() {
        System.out.println("is waxon?");
        return waxOn;
    }

    public synchronized void waxed() {
        waxOn = true;
        notifyAll();
    }

    public synchronized void buffed() {
        waxOn = false;
        notifyAll();
    }

    public void waitForWaxed() {
        synchronized (this) {
            while (!isWaxOn()) {
                try {
                    wait();
                } catch (InterruptedException e) {

                }
            }
        }
    }

    public void waitForBuffed() {
        synchronized (this) {
            while (isWaxOn()) {
                try {
                    wait();
                } catch (InterruptedException e) {
                }
            }
        }
    }
}

class WaxOn implements Runnable {
    private Car car;

    public WaxOn(Car car) {
        this.car = car;
    }

    @Override
    public void run() {
        try {
            while (!Thread.interrupted()) {
                car.waitForBuffed();
                System.out.println("wax on");
                car.waxed();

                TimeUnit.MILLISECONDS.sleep(200);
            }
        } catch (InterruptedException e) {
            System.out.println("waxOn out!");
        }
    }
}

class WaxOff implements Runnable {
    private Car car;

    public WaxOff(Car car) {
        this.car = car;
    }

    @Override
    public void run() {
        try {
            while (!Thread.interrupted()) {
                car.waitForWaxed();
                System.out.println("wax off");
                car.buffed();
                TimeUnit.MILLISECONDS.sleep(200);
            }
        } catch (InterruptedException e) {
            System.out.println("waxOff out");
        }
    }
}